﻿using System;
using System.Transactions;
using System.Web.Security;
using TestWebApplication.Models.DataAccess;
using TestWebApplication.Models.Entities;
using TestWebApplication.Models.Forms;

namespace TestWebApplication.Models
{
    public class AuthService : IAuthService
    {
        private readonly IStorage storage;
        private readonly INotificationService notificationService;

        public AuthService(IStorage storage, INotificationService notificationService)
        {
            if (storage == null)
            {
                throw new ArgumentNullException("storage");
            }
            if (notificationService == null)
            {
                throw new ArgumentNullException("notificationService");
            }

            this.storage = storage;
            this.notificationService = notificationService;
        }

        public void RegisterUser(UserRegistrationForm registration, string baseUrl)
        {
            var user = new User
                           {
                               Login = registration.LoginName,
                               Email = registration.Email,
                               PasswordHash = GetPasswordHash(registration.Password),
                               IsActive = false,
                               ActivationKey = GetNewGuid(),
                               Birthday = registration.GetBirthayAsDateTime(),
                               LacesColor = registration.LacesColor
                           };

            using (var transactionScope = new TransactionScope())
            {
                storage.CreateUser(user);
                notificationService.Notify(user, baseUrl);

                transactionScope.Complete();
            }
        }

        public string ActivateUser(string key, string shoesSize)
        {
            var loginName = storage.ActivateUser(key, shoesSize);

            if (string.IsNullOrEmpty(loginName))
            {
                throw new InvalidOperationException(
                    string.Format("Не удалось активировать пользователя по activationKey='{0}'", key));
            }

            return loginName;
        }

        public bool Logon(string loginName, string password)
        {
            if (string.IsNullOrEmpty(loginName) || string.IsNullOrEmpty(password))
            {
                return false;
            }

            var hash = GetPasswordHash(password);
            var result = storage.IsUserExists(loginName, hash);

            if (result)
            {
                FormsAuthentication.SetAuthCookie(loginName, true);
            }

            return result;
        }

        public void Logoff()
        {
            FormsAuthentication.SignOut();
        }

        public bool HasCreatedUser(string key)
        {
            if (string.IsNullOrEmpty(key))
            {
                return false;
            }

            return storage.HasCreatedUser(key);
        }

        private string GetNewGuid()
        {
            return Guid.NewGuid().ToString("N");
        }

        private string GetPasswordHash(string password)
        {
            return FormsAuthentication.HashPasswordForStoringInConfigFile(password, "sha1");
        }

    }
}